// DateTime类的单元测试
// 使用Google Test框架验证所有功能的正确性

#include "base/DateTime.h"
#include <gtest/gtest.h>
#include <iostream>

using namespace cytoolkit;

// Date类测试
TEST(DateTest, DefaultConstructor) {
    Date date;
    EXPECT_FALSE(date.isValid());
}

TEST(DateTest, ValidDateConstructor) {
    Date date(2023, 10, 15);
    EXPECT_TRUE(date.isValid());
    EXPECT_EQ(2023, date.year());
    EXPECT_EQ(10, date.month());
    EXPECT_EQ(15, date.day());
}

TEST(DateTest, InvalidDateConstructor) {
    Date date(2023, 2, 30); // 2月没有30天
    EXPECT_FALSE(date.isValid());
}

TEST(DateTest, JulianDayConstructor) {
    Date date(Date::kJulianDayOf1970_01_01);
    EXPECT_TRUE(date.isValid());
    EXPECT_EQ(1970, date.year());
    EXPECT_EQ(1, date.month());
    EXPECT_EQ(1, date.day());
}

TEST(DateTest, DayOfWeek) {
    // 2023-10-15是星期日
    Date date(2023, 10, 15);
    EXPECT_EQ(7, date.dayOfWeek());
    
    // 2023-10-16是星期一
    Date date2(2023, 10, 16);
    EXPECT_EQ(1, date2.dayOfWeek());
}

TEST(DateTest, DayOfYear) {
    Date date(2023, 1, 1);
    EXPECT_EQ(1, date.dayOfYear());
    
    Date date2(2023, 12, 31);
    EXPECT_EQ(365, date2.dayOfYear());
    
    // 闰年测试
    Date date3(2024, 12, 31);
    EXPECT_EQ(366, date3.dayOfYear());
}

TEST(DateTest, DaysInMonth) {
    Date date(2023, 2, 1);
    EXPECT_EQ(28, date.daysInMonth());
    
    Date date2(2024, 2, 1); // 闰年
    EXPECT_EQ(29, date2.daysInMonth());
    
    Date date3(2023, 4, 1);
    EXPECT_EQ(30, date3.daysInMonth());
}

TEST(DateTest, AddDays) {
    Date date(2023, 10, 15);
    Date newDate = date.addDays(5);
    
    EXPECT_EQ(2023, newDate.year());
    EXPECT_EQ(10, newDate.month());
    EXPECT_EQ(20, newDate.day());
    
    // 跨月测试
    Date newDate2 = date.addDays(20);
    EXPECT_EQ(2023, newDate2.year());
    EXPECT_EQ(11, newDate2.month());
    EXPECT_EQ(4, newDate2.day());
    
    // 跨年测试
    Date date3(2023, 12, 31);
    Date newDate3 = date3.addDays(1);
    EXPECT_EQ(2024, newDate3.year());
    EXPECT_EQ(1, newDate3.month());
    EXPECT_EQ(1, newDate3.day());
}

TEST(DateTest, AddMonths) {
    Date date(2023, 10, 15);
    Date newDate = date.addMonths(2);
    
    EXPECT_EQ(2023, newDate.year());
    EXPECT_EQ(12, newDate.month());
    EXPECT_EQ(15, newDate.day());
    
    // 跨年测试
    Date newDate2 = date.addMonths(5);
    EXPECT_EQ(2024, newDate2.year());
    EXPECT_EQ(3, newDate2.month());
    EXPECT_EQ(15, newDate2.day());
    
    // 月末日期调整测试
    Date date3(2023, 1, 31);
    Date newDate3 = date3.addMonths(1);
    EXPECT_EQ(2023, newDate3.year());
    EXPECT_EQ(2, newDate3.month());
    EXPECT_EQ(28, newDate3.day()); // 2023年2月只有28天
}

TEST(DateTest, AddYears) {
    Date date(2023, 10, 15);
    Date newDate = date.addYears(1);
    
    EXPECT_EQ(2024, newDate.year());
    EXPECT_EQ(10, newDate.month());
    EXPECT_EQ(15, newDate.day());
    
    // 闰年测试
    Date date2(2024, 2, 29); // 闰年
    Date newDate2 = date2.addYears(1);
    EXPECT_EQ(2025, newDate2.year());
    EXPECT_EQ(2, newDate2.month());
    EXPECT_EQ(28, newDate2.day()); // 调整到2月底
}

TEST(DateTest, DaysTo) {
    Date date1(2023, 10, 15);
    Date date2(2023, 10, 20);
    EXPECT_EQ(5, date1.daysTo(date2));
    EXPECT_EQ(-5, date2.daysTo(date1));
    
    // 跨年测试
    Date date3(2023, 12, 30);
    Date date4(2024, 1, 2);
    EXPECT_EQ(3, date3.daysTo(date4));
}

TEST(DateTest, ToString) {
    Date date(2023, 10, 15);
    EXPECT_EQ("2023-10-15", date.toISOString());
    EXPECT_EQ("2023/10/15", date.toString("YYYY/MM/DD"));
}

TEST(DateTest, FromString) {
    Date date = Date::fromString("2023-10-15");
    EXPECT_TRUE(date.isValid());
    EXPECT_EQ(2023, date.year());
    EXPECT_EQ(10, date.month());
    EXPECT_EQ(15, date.day());
    
    // 无效字符串
    Date invalid = Date::fromString("invalid");
    EXPECT_FALSE(invalid.isValid());
}

TEST(DateTest, IsLeapYear) {
    EXPECT_FALSE(Date::isLeapYear(2023));
    EXPECT_TRUE(Date::isLeapYear(2024));
    EXPECT_TRUE(Date::isLeapYear(2000));
    EXPECT_FALSE(Date::isLeapYear(1900));
}

// Time类测试
TEST(TimeTest, DefaultConstructor) {
    Time time;
    EXPECT_FALSE(time.isValid());
}

TEST(TimeTest, ValidTimeConstructor) {
    Time time(14, 30, 45, 500);
    EXPECT_TRUE(time.isValid());
    EXPECT_EQ(14, time.hour());
    EXPECT_EQ(30, time.minute());
    EXPECT_EQ(45, time.second());
    EXPECT_EQ(500, time.msec());
}

TEST(TimeTest, InvalidTimeConstructor) {
    Time time(25, 0, 0); // 无效小时
    EXPECT_FALSE(time.isValid());
    
    Time time2(0, 60, 0); // 无效分钟
    EXPECT_FALSE(time2.isValid());
}

TEST(TimeTest, MSecsSinceMidnightConstructor) {
    Time time(14 * 3600000 + 30 * 60000 + 45 * 1000 + 500);
    EXPECT_TRUE(time.isValid());
    EXPECT_EQ(14, time.hour());
    EXPECT_EQ(30, time.minute());
    EXPECT_EQ(45, time.second());
    EXPECT_EQ(500, time.msec());
}

TEST(TimeTest, AddHours) {
    Time time(10, 0, 0);
    Time newTime = time.addHours(5);
    EXPECT_EQ(15, newTime.hour());
    EXPECT_EQ(0, newTime.minute());
    EXPECT_EQ(0, newTime.second());
    
    // 跨天测试
    Time newTime2 = time.addHours(20);
    EXPECT_EQ(6, newTime2.hour());
    
    // 负数测试
    Time newTime3 = time.addHours(-5);
    EXPECT_EQ(5, newTime3.hour());
}

TEST(TimeTest, AddMinutes) {
    Time time(10, 30, 0);
    Time newTime = time.addMinutes(45);
    EXPECT_EQ(11, newTime.hour());
    EXPECT_EQ(15, newTime.minute());
    
    // 跨小时测试
    Time newTime2 = time.addMinutes(120);
    EXPECT_EQ(12, newTime2.hour());
    EXPECT_EQ(30, newTime2.minute());
}

TEST(TimeTest, AddSecs) {
    Time time(10, 30, 15);
    Time newTime = time.addSecs(45);
    EXPECT_EQ(10, newTime.hour());
    EXPECT_EQ(31, newTime.minute());
    EXPECT_EQ(0, newTime.second());
}

TEST(TimeTest, AddMSecs) {
    Time time(10, 30, 15, 500);
    Time newTime = time.addMSecs(600);
    EXPECT_EQ(10, newTime.hour());
    EXPECT_EQ(30, newTime.minute());
    EXPECT_EQ(16, newTime.second());
    EXPECT_EQ(100, newTime.msec());
}

TEST(TimeTest, SecsTo) {
    Time time1(10, 0, 0);
    Time time2(10, 5, 30);
    EXPECT_EQ(330, time1.secsTo(time2));
    EXPECT_EQ(-330, time2.secsTo(time1));
}

TEST(TimeTest, ToString) {
    Time time(14, 30, 45, 500);
    EXPECT_EQ("14:30:45", time.toString("HH:MM:SS"));
    EXPECT_EQ("14:30:45.500", time.toString("HH:MM:SS.ms"));
}

TEST(TimeTest, FromString) {
    Time time = Time::fromString("14:30:45.500");
    EXPECT_TRUE(time.isValid());
    EXPECT_EQ(14, time.hour());
    EXPECT_EQ(30, time.minute());
    EXPECT_EQ(45, time.second());
    EXPECT_EQ(500, time.msec());
}

// TimeZone类测试
TEST(TimeZoneTest, UTC) {
    TimeZone tz = TimeZone::utc();
    EXPECT_TRUE(tz.isValid());
    EXPECT_EQ("UTC", tz.name());
    EXPECT_EQ(0, tz.offsetFromUtc());
    EXPECT_FALSE(tz.hasDaylightTime());
}

TEST(TimeZoneTest, FromOffset) {
    TimeZone tz = TimeZone::fromOffset(28800); // UTC+8
    EXPECT_TRUE(tz.isValid());
    EXPECT_EQ(28800, tz.offsetFromUtc());
}

// DateTime类测试
TEST(DateTimeTest, DefaultConstructor) {
    DateTime dt;
    EXPECT_FALSE(dt.isValid());
}

TEST(DateTimeTest, DateAndTimeConstructor) {
    Date date(2023, 10, 15);
    Time time(14, 30, 45);
    DateTime dt(date, time);
    
    EXPECT_TRUE(dt.isValid());
    EXPECT_EQ(2023, dt.year());
    EXPECT_EQ(10, dt.month());
    EXPECT_EQ(15, dt.day());
    EXPECT_EQ(14, dt.hour());
    EXPECT_EQ(30, dt.minute());
    EXPECT_EQ(45, dt.second());
}

TEST(DateTimeTest, FullConstructor) {
    DateTime dt(2023, 10, 15, 14, 30, 45, 500);
    
    EXPECT_TRUE(dt.isValid());
    EXPECT_EQ(2023, dt.year());
    EXPECT_EQ(10, dt.month());
    EXPECT_EQ(15, dt.day());
    EXPECT_EQ(14, dt.hour());
    EXPECT_EQ(30, dt.minute());
    EXPECT_EQ(45, dt.second());
    EXPECT_EQ(500, dt.msec());
}

TEST(DateTimeTest, AddOperations) {
    DateTime dt(2023, 10, 15, 10, 0, 0);
    
    // 测试增加小时
    DateTime newDt = dt.addHours(5);
    EXPECT_EQ(15, newDt.hour());
    
    // 测试增加分钟
    newDt = dt.addMinutes(30);
    EXPECT_EQ(10, newDt.hour());
    EXPECT_EQ(30, newDt.minute());
    
    // 测试增加天数
    newDt = dt.addDays(2);
    EXPECT_EQ(17, newDt.day());
    
    // 测试增加月份
    newDt = dt.addMonths(1);
    EXPECT_EQ(11, newDt.month());
    
    // 测试增加年份
    newDt = dt.addYears(1);
    EXPECT_EQ(2024, newDt.year());
}

TEST(DateTimeTest, TimeDifference) {
    DateTime dt1(2023, 10, 15, 10, 0, 0);
    DateTime dt2(2023, 10, 16, 11, 30, 15);
    
    EXPECT_EQ(1, dt1.daysTo(dt2));
    EXPECT_EQ(95415, dt1.secsTo(dt2)); // 1天1小时30分15秒
    EXPECT_EQ(95415000, dt1.msecsTo(dt2));
}

TEST(DateTimeTest, StringConversion) {
    DateTime dt(2023, 10, 15, 14, 30, 45);
    EXPECT_EQ("2023-10-15 14:30:45", dt.toISOString());
    
    DateTime parsed = DateTime::fromString("2023-10-15 14:30:45");
    EXPECT_TRUE(parsed.isValid());
    EXPECT_EQ(2023, parsed.year());
    EXPECT_EQ(10, parsed.month());
    EXPECT_EQ(15, parsed.day());
    EXPECT_EQ(14, parsed.hour());
    EXPECT_EQ(30, parsed.minute());
    EXPECT_EQ(45, parsed.second());
}

TEST(DateTimeTest, TimestampConversion) {
    // 1970-01-01 00:00:00 UTC
    DateTime dt = DateTime::fromMSecsSinceEpoch(0);
    EXPECT_TRUE(dt.isValid());
    EXPECT_EQ(1970, dt.year());
    EXPECT_EQ(1, dt.month());
    EXPECT_EQ(1, dt.day());
    EXPECT_EQ(0, dt.hour());
    EXPECT_EQ(0, dt.minute());
    EXPECT_EQ(0, dt.second());
    
    // 转换回时间戳
    EXPECT_EQ(0, dt.toMSecsSinceEpoch());
}

TEST(DateTimeTest, ComparisonOperators) {
    DateTime dt1(2023, 10, 15, 10, 0, 0);
    DateTime dt2(2023, 10, 15, 11, 0, 0);
    DateTime dt3(2023, 10, 15, 10, 0, 0);
    
    EXPECT_TRUE(dt1 < dt2);
    EXPECT_FALSE(dt2 < dt1);
    EXPECT_TRUE(dt1 == dt3);
    EXPECT_FALSE(dt1 != dt3);
    
    // 测试所有比较运算符
    EXPECT_TRUE(dt1 <= dt2);
    EXPECT_TRUE(dt2 >= dt1);
    EXPECT_TRUE(dt1 <= dt3);
    EXPECT_TRUE(dt1 >= dt3);
}

// DateTimeUtils测试
TEST(DateTimeUtilsTest, IsValidDate) {
    EXPECT_TRUE(DateTimeUtils::isValidDate(2023, 10, 15));
    EXPECT_FALSE(DateTimeUtils::isValidDate(2023, 2, 30));
    EXPECT_TRUE(DateTimeUtils::isValidDate(2024, 2, 29)); // 闰年
}

TEST(DateTimeUtilsTest, IsValidTime) {
    EXPECT_TRUE(DateTimeUtils::isValidTime(14, 30, 45, 500));
    EXPECT_FALSE(DateTimeUtils::isValidTime(25, 0, 0));
    EXPECT_FALSE(DateTimeUtils::isValidTime(0, 60, 0));
}

TEST(DateTimeUtilsTest, DaysInMonth) {
    EXPECT_EQ(31, DateTimeUtils::daysInMonth(2023, 1));
    EXPECT_EQ(28, DateTimeUtils::daysInMonth(2023, 2));
    EXPECT_EQ(29, DateTimeUtils::daysInMonth(2024, 2)); // 闰年
    EXPECT_EQ(30, DateTimeUtils::daysInMonth(2023, 4));
}

TEST(DateTimeUtilsTest, IsLeapYear) {
    EXPECT_FALSE(DateTimeUtils::isLeapYear(2023));
    EXPECT_TRUE(DateTimeUtils::isLeapYear(2024));
    EXPECT_TRUE(DateTimeUtils::isLeapYear(2000));
    EXPECT_FALSE(DateTimeUtils::isLeapYear(1900));
}

// Rate类测试（简单测试，不实际执行sleep）
TEST(RateTest, ConstructorAndReset) {
    Rate rate(10.0f); // 10Hz
    // 重置为5Hz
    rate.reset(5.0f);
    // 这里不测试sleep，因为会影响测试性能
}

// 主函数
int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}